#include "net.h"


// 自定义数据结构
typedef struct SockInfo
{
    int fd; // 
    struct sockaddr_in addr;
    pthread_t id;
}SockInfo;

// 子线程处理函数
void* worker(void* arg)
{
    char ip[64];
    char buf[64];
    int real_read;
    SockInfo* info = (SockInfo*)arg;
    // 通信
    while(1)
    {

		bzero(buf,sizeof(buf));
		if( (real_read = read(info->fd,buf,sizeof(buf))) < 0)
		{
			perror("recv");
			pthread_exit(NULL);		//结束线程
		}
		
		if( 0 == real_read)
		{//客户端断开连接
			close(info->fd);
			printf("client break\n");
			break;
		}

		printf("Received: %s\n",buf);

		if( 0 == (strncasecmp(buf,QUIT_STR,strlen(QUIT_STR))) )
		{
			printf("client quit\n");
			break;
		}

		bzero(buf,sizeof(buf));

		printf(">");

		fgets(buf,32,stdin);

		write(info->fd,buf,strlen(buf)-1);

		if( 0 == (strncasecmp(buf,QUIT_STR,strlen(QUIT_STR))) )
		{
			printf("client quit\n");
			break;
		}
    }
    return NULL;
}

int main(int argc, const char *argv[])
{
	int listenfd;
	struct sockaddr_in servaddr;
	socklen_t peerlen;

	//填充结构体servaddr信息
	bzero(&servaddr,sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	inet_pton(AF_INET,SERV_IP_ADDR,(void *)&servaddr.sin_addr);
	servaddr.sin_port = htons(SERV_PORT);

	if( -1 == (listenfd = socket(AF_INET,SOCK_STREAM,0)) )
	{//1.建立监听套接字
		perror("socket failed");
		return -1;
	}	
	printf("socket create success....\n");

	if(-1 == bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) )
	{//2.绑定IP和端口信息
		perror("bind failed");
		return -1;
	}
	printf("bind success....\n");

	if( -1 == listen(listenfd,10) )
	{//3.设置端口监听
		perror("listen failed");
		return -1;
	}
	printf("listen success....\n");


    int i = 0;
    SockInfo info[256];
    // 规定 fd == -1  
    for(i=0; i<sizeof(info)/sizeof(info[0]); ++i)
    {
        info[i].fd = -1;
    }

	// bzero(&cliaddr,sizeof(cliaddr));
	peerlen = sizeof(struct sockaddr_in);
	while(1)
	{//4.父线程中等待客户端连接

        
        for(i=0; i<256; ++i)
        {//选一个没有被使用的, 最小的数组元素
            if(info[i].fd == -1)
            {
                break;
            }
        }
        if(i == 256)
        {
            break;
        }
        // 主线程 - 等待接受连接请求
        info[i].fd = accept(listenfd,(struct sockaddr *)&info[i].addr,&peerlen);
        // 创建子线程 - 通信
        pthread_create(&info[i].id, NULL, worker, &info[i]);
        // 设置线程分离
        pthread_detach(info[i].id);
	}
	
	close(listenfd);

    //5.只退出主线程
    pthread_exit(NULL);
	return 0;
}
